﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml.Linq;
using System.Xml.Serialization;
using System.IO;
using System.Xml;

namespace SinaAPIDocumentToRequestTool
{

    public partial class XmlViewer : Form
    {
        internal XmlViewer()
        {
            InitializeComponent();
        }

        public XmlViewer(DocumentDataGetterBase dataGetter)
        {
            InitializeComponent();
            _dataGetter = dataGetter;
            dic = _dataGetter.GetParamsAndParamsComment();
        }

        private void RefreshXml(DocumentDataGetterBase dataGetter)
        {
            object request;
            var files = dic

                .Where(kvp => kvp.Value[1] == "binary")
                .Select(
                    kvp =>
                    new paramForceSingle
                    {
                        Comment = kvp.Value[3],
                        key = kvp.Key,
                        type = paramTypeForceSingle.Single
                    }
                )
                .ToArray();

            var urlTmplates = dic
                .Where(kvp => kvp.Key.StartsWith(":"))
                .Select(
                    kvp =>
                    new paramForceSingle
                    {
                        Comment = kvp.Value[3],
                        key = kvp.Key.Substring(1),
                        type = paramTypeForceSingle.Single
                    }
                )
                .ToArray();


            var fields = dic
            .Where(kvp => kvp.Value[1] != "binary" && (!kvp.Key.StartsWith(":")))
            .Select(
                kvp =>
                new param
                {
                    Comment = kvp.Value[3],
                    key = kvp.Key,
                    type = kvp.Value[2].EndsWith("[]") ? paramType.List : paramType.Single
                }
            )
            .ToArray();

           // var paths = txtTarget.Text.Split('/');
            //var baspath = paths.Select(x=>x.Replace(":","")).ToArray();
            var finalPath = txtTarget.Text.Replace(":","");
            
            PathMore = finalPath;
            var tempstbr = new StringBuilder(txtTarget.Text);

            urlTmplates.ToList()
                .ForEach
                (
                    s =>
                    {
                        tempstbr.Replace(":" + s.key, "{" + s.key + "}");
                    }
                );

            var tmplate = new TemplateValueSet
            {
                param = urlTmplates,
                Template = new Template { url = tempstbr.ToString() + ".json" }
            };
            
            if (_dataGetter.GetWebMethod().IndexOf("POST") != -1)
            {

                if (files.Length > 0)
                {
                    request = new rootMultiPartPostRequest()
                    {
                        Comment = _dataGetter.GetComment(),
                        File = files,
                        URLTemplate = tmplate,
                        Post = fields
                    };
                }
                else
                {
                    request = new rootPostRequest()
                    {
                        Comment = _dataGetter.GetComment(),
                        URLTemplate = tmplate,
                        Post = fields
                    };
                }
            }
            else
            {
                request = new rootGetRequest()
                {
                    Comment = _dataGetter.GetComment(),
                    URLTemplate = tmplate,
                    Query = fields

                };

            }

            var xmlSerializer = new XmlSerializer(typeof(root));
            var ms = new MemoryStream();

            xmlSerializer.Serialize(ms, new root { Item = request });
            ms.Position=0;
            var doc =XDocument.Load(ms);
            doc.Descendants().Where(x => x.Name.LocalName == "Comment")
                .ToList()
                .ForEach(
                    x =>
                    {
                        var v = x.Value;
                        x.Value = "";
                        var cdd = new XCData(v);
                        x.Add(cdd);

                    }
                );

            textBox1.Text = doc.ToString();
        }
        public string PathRoot { get; set; }

        public string PathMore { get; set; }
        IDictionary<string, string[]> dic;
        DocumentDataGetterBase _dataGetter;


        private void XmlViewer_Load(object sender, EventArgs e)
        {

            this.txtRequestComment.Text = _dataGetter.GetComment();
            this.txtRequestMethod.Text = _dataGetter.GetWebMethod();
            this.lbxParams.Items.AddRange(dic.Keys.ToArray());
            this.txtTarget.Text = this._dataGetter.GetPath();
            this.textBox2.Text = _dataGetter.GetJsonResponse();
            RefreshXml(_dataGetter);
        }

        private void lbxParams_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (lbxParams.SelectedIndex != -1)
            {
                txtParamComment.Text = dic[lbxParams.SelectedItem.ToString()].Last();
            }
        }

        private void toolStripButton1_Click(object sender, EventArgs e)
        {
            var fn = Path.Combine(PathRoot, PathMore + ".Request.xml");
            var fn2 = Path.Combine(PathRoot, PathMore + ".Response.json");
            WriteFile(fn, textBox1.Text);
            WriteFile(fn2, textBox2.Text);
            
        }

        private void WriteFile(string fn,string text)
        {
            var path = Path.GetDirectoryName(fn);
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
            if (File.Exists(fn))
            {
                var val = File.GetAttributes(fn);
                if ((val & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
                    File.SetAttributes(fn, File.GetAttributes(fn) ^ FileAttributes.ReadOnly);
            }

            try
            {
                File.WriteAllText(fn,text,  Encoding.UTF8);
                MessageBox.Show(fn, "已经写入文件");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, ex.Source);
            }

        }

        private void button1_Click(object sender, EventArgs e)
        {
            RefreshXml(_dataGetter);
        }

        private void button2_Click(object sender, EventArgs e)
        {
            var v = new StringBuilder(textBox2.Text).Replace("”", "\"");
            textBox2.Text = v.ToString();
        }



    }
}
